import * as React from "react";

const { useState, useEffect, useRef } = React;

const getTargetElement = (ref) => typeof ref === 'function' ? ref() : ref?.current

function useInViewport(target, options) {
  const [state, setState] = useState();
  const [ratio, setRatio] = useState();

  useEffect(
    () => {
      // 获取元素真实节点
      const el = getTargetElement(target);

      if (!el) {
        return;
      }

      // 异步观察元素与祖先元素或者可视窗口的交叉状态
      const observer = new IntersectionObserver(
        (entries) => {
          for (const entry of entries) {
            // 元素与root或者视口的交叉比例
            setRatio(entry.intersectionRatio);

            // 元素是否与 root 或者 视口 交叉
            if (entry.isIntersecting) {
              setState(true);
            } else {
              setState(false);
            }
          }
        },
        {
          ...options,
          root: getTargetElement(options?.root), // 与祖先元素的交叉状态，默认是可视窗口
        }
      );

      // 监听该元素与视口交叉露出尺寸信息
      observer.observe(el);

      return () => {
        observer.disconnect();
      };
    },
    [],
    target
  );

  return [state, ratio];
}

export default () => {
  // const ref = useRef(null);
  // const [inViewport, radio] = useInViewport(ref);
  // return (
  //   <div>
  //     <div style={{ width: 300, height: 300, overflow: 'scroll', border: '1px solid' }}>
  //       scroll here
  //       <div style={{ height: 800 }}>
  //         <div
  //           ref={ref}
  //           style={{
  //             border: '1px solid',
  //             height: 100,
  //             width: 100,
  //             textAlign: 'center',
  //             marginTop: 80,
  //           }}
  //         >
  //           observer dom
  //         </div>
  //       </div>
  //     </div>
  //     <div style={{ marginTop: 16, color: inViewport ? '#87d068' : '#f50' }}>
  //       inViewport: {inViewport ? 'visible' : 'hidden'}
  //       <p>radio: {radio}</p>
  //     </div>
  //   </div>
  // );
  const [inViewport, ratio] = useInViewport(
    () => document.getElementById("parent"),
    {
      threshold: [0, 0.25, 0.5, 0.75, 1], // 交叉比例到达这些的时候触发回调
      // root: () => document.getElementById("parent"),
    }
  );
  return (
    <div>
      <div
        style={{
          width: 300,
          height: 300,
          overflow: "scroll",
          border: "1px solid",
        }}
        id="parent"
      >
        scroll here
        <div style={{ height: 800 }}>
          <div
            id="children"
            style={{
              border: "1px solid orange",
              height: 100,
              width: 100,
              textAlign: "center",
              marginTop: 80,
            }}
          >
            observer dom
          </div>
        </div>
      </div>
      <div style={{ marginTop: 16, color: inViewport ? "#87d068" : "#f50", position: 'fixed', bottom: 20, left: 20 }}>
        <p>inViewport: {inViewport ? "visible" : "hidden"}</p>
        <p>ratio: {ratio}</p>
      </div>
    </div>
  );
};
